import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'

interface ICustomRequestConfig extends AxiosRequestConfig {
  useLoading?: boolean
  useError?: boolean
}

interface IRequest {
  (url: string, params?: Record<string, unknown>, config?: ICustomRequestConfig): Promise<AxiosResponse<unknown>>
}

const isDev = import.meta.env.DEV
const devProxyPrefix = import.meta.env['VITE_APP_PROXY_PREFIX']
const VITE_APP_CUSTOM_PROXY_PATTEN: string = import.meta.env['VITE_APP_CUSTOM_PROXY_PATTEN'] as string
const regxCustomProxy = new RegExp(VITE_APP_CUSTOM_PROXY_PATTEN)
const regxHttp = /^http(s?):\/\//

// 后台定义的状态码
enum RESPONSE_STATUS {
  SUCCESS = 20000,
  INVALID_TOKEN = 5000,
}

export function withProxy(url = ''): string {
  if (regxHttp.test(url)) {
    return url
  }

  if (regxCustomProxy.test(url)) {
    const originRequestUrl = url.replace(regxCustomProxy, '')
    return isDev ? url : originRequestUrl
  } else {
    return isDev ? `${devProxyPrefix}${url}` : url
  }
}

const axiosInstance = axios.create({
  timeout: 10000,
  responseType: 'json',
  headers: {
    'Content-Type': 'application/json;charset=utf-8',
  },
})

axiosInstance.interceptors.request.use((config: ICustomRequestConfig = {}) => {
  if (config.useLoading) {
    // 使用全局loading
  }

  config.headers['Authorization'] = window.localStorage.getItem('token') || ''
  config.url = withProxy(config.url)

  return config
})

axiosInstance.interceptors.response.use(
  (res) => {
    if (res?.data?.code !== undefined) {
      switch (res?.data?.code) {
        case RESPONSE_STATUS.SUCCESS:
          return res.data
        case RESPONSE_STATUS.INVALID_TOKEN:
          return Promise.reject('登录过期')
        default:
          return Promise.reject('请求失败')
      }
    } else {
      return Promise.reject(res)
    }
  },
  (err) => {
    if (err && typeof err.toJSON === 'function') {
      const { useError } = err.toJSON().config || {}
      useError && console.error('网络异常', err)
    }

    return Promise.reject(err)
  }
)

export const get: IRequest = (url = '', params = {}, config = {}) => axiosInstance.get(url, { params, ...config })
export const post: IRequest = (url = '', params = {}, config = {}) =>
  axiosInstance.post(url, { data: params, ...config })
